/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package metodos;

import datos.Datos;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;

public class Bayes{

    
    private Datos datos;
    private ArrayList<String> valoresClase;
    private ArrayList<ArrayList<String>> tablaAtributos;
    private ArrayList<ArrayList<String>> valoresAtributos;
    private ArrayList<ArrayList<String>> tablaPorcentajes;
    private ArrayList<String> totalesColumna;
    private ArrayList<String> aux;
    private ArrayList<String> aux2;
    private ArrayList<String> aux3;
    private ArrayList<Float> porcentajesClase;
    private BayesGUIcontroller byg;
    
    public Bayes(Datos datos){
        this.datos = datos;
        valoresClase = new ArrayList<String>();
        tablaAtributos = new ArrayList<ArrayList<String>>();
        tablaPorcentajes = new ArrayList<ArrayList<String>>();
        valoresAtributos = new ArrayList<ArrayList<String>>();
        totalesColumna = new ArrayList<String>();
        aux = new ArrayList<String>();
        aux2 = new ArrayList<String>();
        aux3 = new ArrayList<String>();
        porcentajesClase = new ArrayList<Float>();
    }
    
   public ArrayList<String> getTitulos(){
        int a = getIndiceClase();
        ArrayList<String> auxiliarTitulos = new ArrayList<String>();
        
        for(int i = 0; i < datos.getTitulos().length; i++){
            if(i != a)
                auxiliarTitulos.add(datos.getTitulos()[i]);
        }
        
        return auxiliarTitulos;
    }
    //Calcula el indice de la clase seleccionada por el usuario
    public int getIndiceClase(){
        
        for (int i = 0; i < getDatos().getTitulos().length; i++) {
            
            if(getDatos().getNombreClase().equals(getDatos().getTitulos()[i])){
                return i;
            }
        }
        
        return 0;
    }
    
    //Se obtienen los valores que puede tomar la clase y los valores en una lista
    //de los atributos
    public void llenarValores(){
        int indice = getIndiceClase();
        ArrayList<String> aux4 = new ArrayList<String>();        
        for (int i = 0; i < getDatos().getLista().size(); i++) {
            getValoresClase().add(getDatos().getLista().get(i).get(indice));
            getAux().add(getDatos().getLista().get(i).get(indice));
        }
        
        //Borro lo que se repita
        HashSet hs = new HashSet();
        hs.addAll(getValoresClase());
        getValoresClase().clear();
        getValoresClase().addAll(hs);
        hs.clear();
        
        //Desde aquí se hace el llenado de los valores de los atributos obvio
        //sin incluir la clase
        if(indice != 0){
            for (int i = 0; i < getDatos().getLista().get(i).size(); i++) {
                
                if(i != indice){
                    for (int j = 0; j < getDatos().getLista().size(); j++) {

                            getAux2().add(getDatos().getLista().get(j).get(i));
                    }

                    hs.addAll(getAux2());
                    getAux2().clear();
                    getAux2().addAll(hs);
                    hs.clear();
                    Collections.sort(getAux2());
                    getAux2().add("---");

                    for (int h = 0; h < getAux2().size(); h++) {

                        getAux3().add(getAux2().get(h));
                        getTablaAtributos().add(getAux3());
                        setAux3(new ArrayList<String>());   
                    }

                    setAux2(new ArrayList<String>());
               }
            }
            
            for(int i = 0; i < getTablaAtributos().size(); i++){
                if(getTablaAtributos().get(i).get(0).equals("---")){
                    getValoresAtributos().add(aux4);
                    aux4 = new ArrayList<String>();
                    continue;
                }
                else{
                    aux4.add(getTablaAtributos().get(i).get(0));
                }
            }
            
        }
        else{
            
            for (int i = 1; i < getDatos().getLista().get(i).size(); i++) {

                for (int j = 0; j < getDatos().getLista().size(); j++) {
                    //if(i != indice)
                        getAux2().add(getDatos().getLista().get(j).get(i));
                }
                
                hs.addAll(getAux2());
                getAux2().clear();
                getAux2().addAll(hs);
                hs.clear();
                Collections.sort(getAux2());
                getAux2().add("---");

                for (int h = 0; h < getAux2().size(); h++) {

                    getAux3().add(getAux2().get(h));
                    getTablaAtributos().add(getAux3());
                    setAux3(new ArrayList<String>());   
                }

                setAux2(new ArrayList<String>());
            }
        }
        
        for(int i = 0; i < getTablaAtributos().size(); i++){
                if(getTablaAtributos().get(i).get(0).equals("---")){
                    getValoresAtributos().add(aux4);
                    aux4 = new ArrayList<String>();
                    continue;
                }
                else{
                    aux4.add(getTablaAtributos().get(i).get(0));
                }
        }
    }
    
    public void verificarCero(){
        boolean bandera = false;
        for(int i = 0; i < getTablaAtributos().size(); i++){
            for(int j = 0; j < getTablaAtributos().get(0).size(); j++){
                if(getTablaAtributos().get(i).get(0).equals("---")){
                    continue;
                }
                else{
                    getTablaAtributos().get(i).get(j).equals("0");
                    bandera = true;
                }
            }
        }
        
        if(bandera)
            sumarUno();
    }
    
    public void sumarUno(){
        String auxiliar;
        int auxiliar2;
        
        for(int i = 0; i < getTablaAtributos().size(); i++){
            for(int j = 1; j < getTablaAtributos().get(0).size(); j++){
                auxiliar = getTablaAtributos().get(i).get(j);
                auxiliar2 = Integer.parseInt(auxiliar);
                auxiliar2++;
                auxiliar = String.valueOf(auxiliar2);
                getTablaAtributos().get(i).set(j, auxiliar);
            }
        }

    }

    //Conteo:
    public void conteo(){
        
        String temporal;
        int indiceClase = getIndiceClase();
        int contador = 0;
        
        for(int k = 0; k < getTablaAtributos().size(); k++){
   
                temporal = getTablaAtributos().get(k).get(0);
                
                for(int w = 0; w < getValoresClase().size(); w++){
                    
                    contador = 0;
                    for (int i = 0; i < getDatos().getLista().get(0).size(); i++) {

                        for (int j = 0; j < getDatos().getLista().size(); j++) {

                                if(i != indiceClase){

                                        if(temporal.equals(getDatos().getLista().get(j).get(i))){

                                        if(getDatos().getLista().get(j).get(indiceClase).equals(
                                                    getValoresClase().get(w))){

                                                contador++;
                                        }
                                    }
                                } 
                            }
                    }
                    getTablaAtributos().get(k).add(String.valueOf(contador));
                }
            
        }
        for (int i = 0; i < tablaAtributos.size(); i++) {
            
            System.out.println(tablaAtributos.get(i));
        }
        verificarCero();
    }
    
    public void imprimir(){
        System.out.println("Clase: " + getDatos().getNombreClase());
        System.out.println("Valores clase: " + getValoresClase());
        System.out.println("Porcentajes clase: " + getPorcentajesClase());
        System.out.println("\nConteo: ");
        for (int i = 0; i < getTablaAtributos().size(); i++) {
            System.out.println(getTablaAtributos().get(i));
            }
        System.out.println("\nPorcentajes conteo: ");
        for (int j = 0; j < getTablaPorcentajes().size(); j++) {
            System.out.println(getTablaPorcentajes().get(j));    
        }
        
        for (int j = 0; j < getValoresAtributos().size(); j++) {
            System.out.println(getValoresAtributos().get(j));    
        }
    }
    
    public void conteoPorcentajes(){
        float total = 0;
        int k = 0;
        int j = 0;
        
        for(int m = 0; m < getTablaAtributos().get(0).size()-1; m++){
            
            for (int i = 0; i < getTablaAtributos().size(); i++) {

                if(getTablaAtributos().get(j).get(0).equals("---")){
                        //System.out.println("Total vale: " + total);
                        getTotalesColumna().add(String.valueOf(total));
                        k++;
                        j = 0;
                        total = 0;
                        break;
                    }
                    else{
                        total += Float.parseFloat(getTablaAtributos().get(j).get(k+1));
                    }
                    j++;    
             }
        }
        System.out.println(totalesColumna);
        
        
        for(int i = 0; i < getTablaAtributos().size(); i++){
            ArrayList<String> a = new ArrayList<String>();
            for(int m = 0; m < getTablaAtributos().get(i).size(); m++){
                a.add(getTablaAtributos().get(i).get(m));
            }
            getTablaPorcentajes().add(a);
        }
        
        float variable;
        float variable2;
        
        for(int i = 0; i < getTablaPorcentajes().size(); i++){
            for(int p = 1; p < getTablaPorcentajes().get(0).size(); p++){
                variable = Float.parseFloat(getTablaPorcentajes().get(i).get(p));
                variable2 = (variable / Float.parseFloat(getTotalesColumna().get(p-1)));
                getTablaPorcentajes().get(i).set(p, String.valueOf(variable2));
            }
//            System.out.println(tablaPorcentajes.get(i));
        }
    }
    
    //Dependiendo de la clase escogida por el usuario determina el porcentaje
    //de los diferentes valores que tenga.
    public void determinarPorcentajesClase(){
        float contador;
        llenarValores();
        float total = getAux().size();
        
        for (int i = 0; i < getValoresClase().size(); i++) {
            contador = 0;
            for (int j = 0; j < getAux().size(); j++) {
                
                if(getValoresClase().get(i).equals(getAux().get(j)))
                    contador++;
            }
            
            getPorcentajesClase().add(contador/total);
        }
        System.out.println(porcentajesClase);
    }
    
    
    public ArrayList<ArrayList<String>> calcular(ArrayList<String> a){
        String auxiliarCalculo;
        Float sumatoria = 0f;
        ArrayList<String> auxResultado = new ArrayList<String>();
        ArrayList<Float> values2 = new ArrayList<Float>();
        ArrayList<Float> resultados = new ArrayList<Float>();
        ArrayList<Float> productos = new ArrayList<Float>();
        ArrayList<ArrayList<String>> resultado = new ArrayList<ArrayList<String>>();
        ArrayList<ArrayList<Float>> values = new ArrayList<ArrayList<Float>>();
        
        for(int i = 0; i < a.size(); i++){
            auxiliarCalculo = a.get(i);
            
            for(int j = 0; j < tablaPorcentajes.size(); j++){
                
                if(tablaPorcentajes.get(j).get(0).equals(auxiliarCalculo)){
                    for(int k = 1; k < tablaPorcentajes.get(j).size(); k++){
                        values2.add(Float.parseFloat(tablaPorcentajes.get(j).get(k)));
                    }
                    values.add(values2);
                    values2 = new ArrayList<Float>();
                    break;
                }
            }
        }
        
        for(int i = 0; i < values.size(); i++){
            System.out.println(values.get(i));
        }
        
        float auxiliarCalculo2 = 1;
        
        for(int i = 0; i < porcentajesClase.size(); i++){
            for(int j = 0; j < values.size(); j++){
                auxiliarCalculo2 *= values.get(j).get(i);
            }
            auxiliarCalculo2 *= porcentajesClase.get(i);
            productos.add(auxiliarCalculo2);
            auxiliarCalculo2 = 1;
        }
        
        System.out.println(productos);
        
        for(int i = 0; i < productos.size(); i++){
            sumatoria += productos.get(i);
        }
        System.out.println(sumatoria);
        
        for(int i = 0; i < productos.size(); i++){
            resultados.add(productos.get(i)/sumatoria);
        }
        
       System.out.println(resultados);
        a.add("Resultados");
        resultado.add(a);
        
        for(int i = 0; i < values.get(0).size(); i++){
            for(int j = 0; j < values.size(); j++){
                auxResultado.add(String.valueOf(values.get(j).get(i)));
            }
            auxResultado.add(String.valueOf(resultados.get(i)));
            resultado.add(auxResultado);
            auxResultado = new ArrayList<String>();
        }
        
        for (int i = 0; i < resultado.size(); i++) {
            System.out.println(resultado.get(i));
            
        }
        return resultado;
    }
    
    /**
     * @return the datos
     */
    public Datos getDatos() {
        return datos;
    }

    /**
     * @param datos the datos to set
     */
    public void setDatos(Datos datos) {
        this.datos = datos;
    }

    /**
     * @return the valoresClase
     */
    public ArrayList<String> getValoresClase() {
        return valoresClase;
    }

    /**
     * @param valoresClase the valoresClase to set
     */
    public void setValoresClase(ArrayList<String> valoresClase) {
        this.valoresClase = valoresClase;
    }

    /**
     * @return the tablaAtributos
     */
    public ArrayList<ArrayList<String>> getTablaAtributos() {
        return tablaAtributos;
    }

    /**
     * @param tablaAtributos the tablaAtributos to set
     */
    public void setTablaAtributos(ArrayList<ArrayList<String>> tablaAtributos) {
        this.tablaAtributos = tablaAtributos;
    }

    /**
     * @return the tablaPorcentajes
     */
    public ArrayList<ArrayList<String>> getTablaPorcentajes() {
        return tablaPorcentajes;
    }

    /**
     * @param tablaPorcentajes the tablaPorcentajes to set
     */
    public void setTablaPorcentajes(ArrayList<ArrayList<String>> tablaPorcentajes) {
        this.tablaPorcentajes = tablaPorcentajes;
    }

    /**
     * @return the totalesColumna
     */
    public ArrayList<String> getTotalesColumna() {
        return totalesColumna;
    }

    /**
     * @param totalesColumna the totalesColumna to set
     */
    public void setTotalesColumna(ArrayList<String> totalesColumna) {
        this.totalesColumna = totalesColumna;
    }

    /**
     * @return the aux
     */
    public ArrayList<String> getAux() {
        return aux;
    }

    /**
     * @param aux the aux to set
     */
    public void setAux(ArrayList<String> aux) {
        this.aux = aux;
    }

    /**
     * @return the aux2
     */
    public ArrayList<String> getAux2() {
        return aux2;
    }

    /**
     * @param aux2 the aux2 to set
     */
    public void setAux2(ArrayList<String> aux2) {
        this.aux2 = aux2;
    }

    /**
     * @return the aux3
     */
    public ArrayList<String> getAux3() {
        return aux3;
    }

    /**
     * @param aux3 the aux3 to set
     */
    public void setAux3(ArrayList<String> aux3) {
        this.aux3 = aux3;
    }

    /**
     * @return the porcentajesClase
     */
    public ArrayList<Float> getPorcentajesClase() {
        return porcentajesClase;
    }

    /**
     * @param porcentajesClase the porcentajesClase to set
     */
    public void setPorcentajesClase(ArrayList<Float> porcentajesClase) {
        this.porcentajesClase = porcentajesClase;
    }

    /**
     * @return the byg
     */
    public BayesGUIcontroller getByg() {
        return byg;
    }

    /**
     * @param byg the byg to set
     */
    public void setByg(BayesGUIcontroller byg) {
        this.byg = byg;
    }

    /**
     * @return the valoresAtributos
     */
    public ArrayList<ArrayList<String>> getValoresAtributos() {
        return valoresAtributos;
    }
    
}
